package net.qiqbframework.persisthanding.dao;

import java.lang.reflect.Field;
import java.util.*;

public interface BasicEntityPoDao<Po extends BasicEntityPo> {
    /**
     * 将两个对象每个字段进行比较，并返回新对象的差异集合。
     *
     * @param newPo        新对象
     * @param oldPo        旧对象
     * @param ignoreFields 忽略字段名
     * @return key：差异的字段名，value：新对象的字段值
     */
    default Map<String, Object> comparePo(Po newPo, Po oldPo, String... ignoreFields) {
        if (newPo == null) {
            throw new IllegalStateException("newPo is null");
        }
        if (oldPo == null) {
            throw new IllegalStateException("oldPo is null");
        }
        if (!newPo.getId().equals(oldPo.getId())) {
            throw new IllegalStateException("The ids of the comparison objects are not equal!");
        }
        Map<String, Object> changedFields = new HashMap<>();

        // 获取 PO 类的所有字段
        Field[] fields = newPo.getClass().getDeclaredFields();

        for (Field field : fields) {
            if (ignoreFields != null && Arrays.asList(ignoreFields).contains(field.getName())) {
                continue;
            }
            field.setAccessible(true);
            try {
                Object oldValue = field.get(oldPo);  // 获取旧值
                Object newValue = field.get(newPo);  // 获取新值

                // 如果字段的值不同，或者旧值为 null 新值不为 null，添加到更新字段列表
                if ((oldValue == null && newValue != null) || (oldValue != null && !oldValue.equals(newValue))) {
                    changedFields.put(field.getName(), newValue);
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return changedFields;
    }

    List<Po> batchSelectPosByIds(Collection<String> ids);

    /**
     * 根据实体ID查询
     *
     * @param id
     * @return
     */
    Po selectPoById(String id);

    /**
     * 动态跟新
     *
     * @param newPo
     * @param oldPo
     * @return
     */
    boolean dynamicUpdateById(Po newPo, Po oldPo);

    /**
     * 批量更新
     *
     * @param newAndOldMap key 新值，value 旧值
     * @return
     */
    boolean batchDynamicUpdateById(Map<Po, Po> newAndOldMap);

    /**
     * 批量新增
     *
     * @param pos
     * @return
     */
    boolean batchInsertPos(Collection<Po> pos);

    /**
     * 根据ID批量删除
     *
     * @param pos
     * @return
     */
    boolean batchDeletePosById(Collection<Po> pos);

}
